package com.fin.quant.app.user;

import com.fin.quant.app.service.SmsService;
import com.fin.quant.app.user.vo.LoginRequest;
import com.fin.quant.app.user.vo.LoginResult;
import com.fin.quant.common.JwtUtils;
import com.fin.quant.instra.mysql.model.UserAccount;
import com.fin.quant.domain.service.UserDomainService;
import com.fin.quant.rpc.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * 登录服务
 */
@Service
@Slf4j
public class LoginService {

    @Autowired
    private UserDomainService userDomainService;

    @Autowired
    private SmsService smsService;

    /**
     * 用户登录
     */
    public Result<LoginResult> login(LoginRequest request) {
        log.info("用户登录请求: phone={}, email={}, loginType={}", 
                request.getPhone(), request.getEmail(), request.getLoginType());

        try {
            // 参数验证
            if (StringUtils.isEmpty(request.getPhone()) && StringUtils.isEmpty(request.getEmail())) {
                return Result.createErrorResult(400, "手机号或邮箱不能为空");
            }

            // 根据登录类型处理
            if ("SMS".equals(request.getLoginType())) {
                return loginBySms(request);
            } else {
                return loginByPassword(request);
            }
        } catch (Exception e) {
            log.error("登录异常", e);
            return Result.createErrorResult(500, "登录失败，请稍后重试");
        }
    }

    /**
     * 密码登录
     */
    private Result<LoginResult> loginByPassword(LoginRequest request) {
        // 查找用户
        String loginName = StringUtils.isEmpty(request.getPhone()) ? request.getEmail() : request.getPhone();
        UserAccount user = userDomainService.findByLoginName(loginName);
        
        if (user == null) {
            return Result.createErrorResult(404, "用户不存在");
        }

        // 检查用户状态
        if (!userDomainService.isUserActive(user)) {
            return Result.createErrorResult(403, "用户账户已被禁用");
        }

        // 验证密码
        if (StringUtils.isEmpty(request.getPassword())) {
            return Result.createErrorResult(400, "密码不能为空");
        }

        String storedHash = user.getPasswordHash();
        String salt = user.getSalt();

        if (!userDomainService.validatePassword(request.getPassword(), storedHash, salt)) {
            return Result.createErrorResult(401, "密码错误");
        }

        // 生成登录结果
        return buildLoginResult(user);
    }

    /**
     * 短信验证码登录
     */
    private Result<LoginResult> loginBySms(LoginRequest request) {
        // 验证短信验证码
        if (StringUtils.isEmpty(request.getVerifyCode())) {
            return Result.createErrorResult(400, "验证码不能为空");
        }

        String phone = StringUtils.isEmpty(request.getPhone()) ? request.getEmail() : request.getPhone();
        if (!smsService.verifyCode(phone, request.getCountryCode(), request.getVerifyCode())) {
            return Result.createErrorResult(401, "验证码错误或已过期");
        }

        // 查找或创建用户
        UserAccount user = userDomainService.findByLoginName(phone);
        if (user == null) {
            // 如果用户不存在，创建新用户（这里简化处理）
            user = createUserByPhone(phone);
            if (user == null) {
                return Result.createErrorResult(500, "创建用户失败");
            }
        }

        // 检查用户状态
        if (!userDomainService.isUserActive(user)) {
            return Result.createErrorResult(403, "用户账户已被禁用");
        }

        // 生成登录结果
        return buildLoginResult(user);
    }

    /**
     * 发送短信验证码
     */
    public Result<LoginResult> sendVerifyCode(String phone, String countryCode) {
        log.info("发送短信验证码: phone={}, countryCode={}", phone, countryCode);

        try {
            if (StringUtils.isEmpty(phone)) {
                return Result.createErrorResult(400, "手机号不能为空");
            }

            // 发送验证码
            boolean success = smsService.sendVerifyCode(phone, countryCode);
            if (!success) {
                return Result.createErrorResult(500, "发送验证码失败，请稍后重试");
            }

            LoginResult result = new LoginResult();
            result.setMessage("验证码已发送");
            return Result.createSuccessResult(result);
        } catch (Exception e) {
            log.error("发送验证码异常", e);
            return Result.createErrorResult(500, "发送验证码失败，请稍后重试");
        }
    }

    /**
     * 构建登录结果
     */
    private Result<LoginResult> buildLoginResult(UserAccount user) {
        try {
            // 生成JWT token
            String token = JwtUtils.generateToken(user.getId(), user.getUsername());
            
            // 更新最后登录时间
            userDomainService.updateLastLogin(user.getId(), "127.0.0.1"); // 这里应该获取真实IP

            // 构建登录结果
            LoginResult loginResult = new LoginResult();
            loginResult.setToken(token);
            loginResult.setUserId(user.getId());
            loginResult.setUsername(user.getUsername());
            loginResult.setEmail(user.getEmail());
            loginResult.setPhone(user.getPhone());
            loginResult.setAvatarUrl(user.getAvatarUrl());
            loginResult.setLoginTime(LocalDateTime.now());
            loginResult.setTokenExpireTime(JwtUtils.getExpirationDateFromToken(token).getTime());

            log.info("用户登录成功: userId={}, username={}", user.getId(), user.getUsername());
            return Result.createSuccessResult(loginResult);
        } catch (Exception e) {
            log.error("构建登录结果失败", e);
            return Result.createErrorResult(500, "登录失败，请稍后重试");
        }
    }

    /**
     * 根据手机号创建用户（简化实现）
     */
    private UserAccount createUserByPhone(String phone) {
        try {
            UserAccount user = new UserAccount();
            user.setPhone(phone);
            user.setUsername("user_" + System.currentTimeMillis());
            user.setStatus("ACTIVE");
            user.setPasswordHash("default:default"); // 简化处理
            user.setCreatedAt(LocalDateTime.now());
            user.setUpdatedAt(LocalDateTime.now());

            // 这里应该调用userDomainService的创建用户方法
            // 为了简化，直接返回用户对象
            user.setId(System.currentTimeMillis());
            return user;
        } catch (Exception e) {
            log.error("创建用户失败", e);
            return null;
        }
    }
}
